package com.xjiye_test.payServer.servletGroup.weixin;

import com.xiaoleilu.hutool.db.Entity;
import com.xiaoleilu.hutool.db.Page;
import com.xiaoleilu.hutool.db.PageResult;
import com.xiaoleilu.hutool.json.JSONUtil;
import com.xiaoleilu.hutool.log.StaticLog;
import com.xiaoleilu.hutool.util.NumberUtil;
import com.xiaoleilu.hutool.util.RandomUtil;
import com.xjiye_test.payServer.dao.OrderDao;
import com.xjiye_test.payServer.serverletUtil.*;
import com.xjiye_test.payServer.pojo.PayRecord;
import org.xml.sax.SAXException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.*;


//@WebServlet(urlPatterns = "/pay/unifiedorder", asyncSupported = true)
public class WeixinUnifiedorder extends HttpServlet {

    protected synchronized void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("UTF-8");
        resp.setHeader("content-type","text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        String reStr=null;
        try {
            req.setCharacterEncoding("UTF-8");
            int size = req.getContentLength();
            InputStream is = req.getInputStream();
            Map mapRequest = XMLParser.getMapFromXML(new String(ReadBytes.readBytes(is, size)));
            //查询订单是否存在
            OrderDao orderdao=new OrderDao();
            List<String> keys= new ArrayList<>();
            List<String> values= new ArrayList<>();
            keys.add("suppOrderNo=");
            values.add(mapRequest.get("out_trade_no").toString());
            keys.add("suppId=");
            values.add(mapRequest.get("mch_id").toString());
            PageResult<Entity> order=orderdao.getDataByCondition(new Page(0,10),keys,values);
            if(order.isEmpty()){
                //构造订单对象
                String transid=IdWorker.getIdWorker().nextId()+"";
                String openid= RandomUtil.randomString(29);
                PayRecord pay=new PayRecord();
                pay.setTime(new Date());
                pay.setAppid(mapRequest.get("appid").toString());
                pay.setSuppId(mapRequest.get("mch_id").toString());
                pay.setWechatOrderNo(transid);
                pay.setSuppOrderNo(mapRequest.get("out_trade_no").toString());
                pay.setOpenid(openid);
                pay.setPaytype("NATIVE");
                pay.setPaystatus("SUCCESS");
                pay.setAmount(Integer.parseInt(mapRequest.get("total_fee").toString()));
                pay.setWechatRefundNo("");
                pay.setSuppRefundNo("");
                pay.setRefundAmount(0);
                pay.setFee(3);
                pay.setFeeAmount((new Double(NumberUtil.round(NumberUtil.mul(Integer.parseInt(mapRequest.get("total_fee").toString())/100,0.003),0))).intValue());
                try {
                    orderdao.addOrderInfo(pay);
                } catch (SQLException e) {
                    e.printStackTrace();
                    return;
                }
                reStr = Signature.getSignFromResponseString("<xml>\n" +
                        "   <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                        "   <return_msg><![CDATA[OK]]></return_msg>\n" +
                        "   <appid><![CDATA["+mapRequest.get("appid")+"]]></appid>\n" +
                        "   <mch_id><![CDATA["+mapRequest.get("mch_id")+"]]></mch_id>\n" +
                        "   <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>\n" +
                        "   <result_code><![CDATA[SUCCESS]]></result_code>\n" +
                        "   <trade_type><![CDATA[NATIVE]]></trade_type>\n" +
                        "   <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>\n" +
                        "   <code_url><![CDATA[http://aaaa.com]]></code_url>\n" +
                        "</xml>", "123456");
                new Thread(new Notify(pay,mapRequest.get("notify_url").toString())).start();
            }else {
                reStr="<xml><return_code><![CDATA[FAIL]]></return_code>\n" +
                        "<return_msg><![CDATA[订单号重复]]></return_msg>\n" +
                        "</xml>";
            }
        } catch (IOException e) {
            e.printStackTrace();
            reStr="<xml><return_code><![CDATA[FAIL]]></return_code>\n" +
                    "<return_msg><![CDATA[XML解析错误]]></return_msg>\n" +
                    "</xml>";
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
            reStr="<xml><return_code><![CDATA[FAIL]]></return_code>\n" +
                    "<return_msg><![CDATA[系统错误]]></return_msg>\n" +
                    "</xml>";
        } catch (SAXException e) {
            e.printStackTrace();
            reStr="<xml><return_code><![CDATA[FAIL]]></return_code>\n" +
                    "<return_msg><![CDATA[编码错误]]></return_msg>\n" +
                    "</xml>";
        }catch (SQLException e) {
            e.printStackTrace();
            reStr="<xml><return_code><![CDATA[FAIL]]></return_code>\n" +
                    "<return_msg><![CDATA[系统错误]]></return_msg>\n" +
                    "</xml>";
        } finally {
            out.println(reStr);
            out.flush();
        }
    }

    protected synchronized void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
}

    class Notify implements Runnable {
        private PayRecord pay;
        private String url;
        public Notify(PayRecord pay,String url){
            this.pay = pay;
            this.url=url;
        }
        public void run(){
            if(pay==null){
                return;
            }
            StaticLog.info("订单参数为：{}", JSONUtil.parseObj(pay).toString());
            String notifyLast="<xml><transaction_id>"+pay.getWechatOrderNo()+"</transaction_id>\n" +
                    "<nonce_str>f38524r6oa6assa7nfro704dbt4exp7z</nonce_str>\n" +
                    "<bank_type>CFT</bank_type>\n" +
                    "<openid>"+ pay.getOpenid()+"</openid>\n" +
                    "<fee_type>CNY</fee_type>\n" +
                    "<mch_id>"+pay.getSuppId()+"</mch_id>\n" +
                    "<cash_fee>200</cash_fee>\n" +
                    "<out_trade_no>"+pay.getSuppOrderNo()+"</out_trade_no>\n" +
                    "<appid>"+pay.getAppid()+"</appid>\n" +
                    "<total_fee>"+pay.getAmount()+"</total_fee>\n" +
                    "<trade_type>NATIVE</trade_type>\n" +
                    "<result_code>SUCCESS</result_code>\n" +
                    "<time_end>20160921104327</time_end>\n" +
                    "<is_subscribe>N</is_subscribe>\n" +
                    "<return_code>SUCCESS</return_code>\n" +
                    "</xml>";
            String notify= null;
            try {
                Thread.sleep(1000);
                notify = Signature.getSignFromResponseString(notifyLast, "123456");
                StaticLog.info("异步通知内容：{}",notify);
                if(null!=notify&&notify.length()!=0){
                    Map<String,String> header=new HashMap<String, String>();
                    header.put("Content-Type","text/xml");
                    HttpUtil.getInstance().doPost(url,notify,header);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
}
